package com.bjpowernode.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.bjpowernode.constant.Constants;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil2 {

    /**
     * 生成一个jwt字符串
     *
     * @return
     */
    public static String createJWT() {
        //组装头数据（头部是固定的）
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        //链式编程
        return JWT.create()
                //头部
                .withHeader(header)

                //负载
                .withClaim("id", 12556)
                .withClaim("nick", "cat")
                .withClaim("phone", "13702020202")
                .withClaim("birthDay", new Date())

                //签名
                .sign(Algorithm.HMAC256(Constants.JWT_SECRET));
    }

    /**
     * 验证jwt
     *
     * @param jwt
     * @return
     */
    public static Boolean verifyJWT(String jwt) {
        try {
            // 使用密钥构建一个JWT验证对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(Constants.JWT_SECRET)).build();
            //验证JWT，如果验证时没有抛出异常，那么验证通过，否则验证失败
            jwtVerifier.verify(jwt);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 解析jwt
     *
     * @param jwt
     * @return
     */
    public static Map<String, Object> parseJWT(String jwt) {
        Map<String, Object> resultMap = new HashMap<>();

        try {
            // 使用密钥构建一个JWT验证对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(Constants.JWT_SECRET)).build();
            //验证JWT，得到一个解码后的jwt对象
            DecodedJWT decodedJWT = jwtVerifier.verify(jwt);

            //通过解码后的jwt对象，可以获取负载中的数据
            Claim id = decodedJWT.getClaim("id");
            Claim nick = decodedJWT.getClaim("nick");
            Claim phone = decodedJWT.getClaim("phone");
            Claim birthDay = decodedJWT.getClaim("birthDay");

            resultMap.put("id",  id.asInt());
            resultMap.put("nick", nick.asString());
            resultMap.put("phone", phone.asString());
            resultMap.put("birthDay", birthDay.asDate());

            return resultMap;
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String jwt = createJWT();
        System.out.println(jwt);

        Boolean verify = verifyJWT(jwt);
        System.out.println(verify);

        Map<String, Object> resultMap = parseJWT(jwt);
        System.out.println(resultMap);
    }
}
